import pytest
from selenium import webdriver
from _pytest import terminal
import time
import os
import pytest
from selenium import webdriver
import os
import allure

_driver = None


print("执行了--conftest--文件")


# 函数上pytest.fixture装饰器
@pytest.fixture()
def login():
    print("输入账号，密码登录")


# 函数级的装饰器前置，yield会在最后一个函数调用后执行yield之后的代码，之前所有的调用都不会执行
@pytest.fixture(scope="module")
def open1():
    print("打开浏览器，并且打开百度首页")

    yield
    print("执行tieldteardown")
    print("最后关闭浏览器")


driver = None


# @pytest.mark.hookwrapper
# def pytest_runtest_makereport(item):
#     pytest_html = item.config.pluginmanager.getplugin('html')
#     outcome = yield
#     report = outcome.get_result()
#     extra = getattr(report, 'extra', [])
#
#     if report.when == 'call' or report.when == 'setup':
#         xfail = hasattr(report, 'wasxfail')
#         if (report.skipped and xfail) or (report.failed and not xfail):
#             file_name = report.nodeid.replace("::", "_") + ".png"
#             screen_img = _capture_screenshot()
#             if file_name:
#                 html = '<div><img src="data:image/png;base64,%s" alt="screenshot" style="width:600px;height:300px;" ' \
#                        'onclick="window.open(this.src)" align="right"/></div>' % screen_img
#                 extra.append(pytest_html.extras.html(html))
#         report.extra = extra

def _capture_screenshot():
    '''
    ** testzkk**
    截图保存为base64，展示到html中
    :return:
    '''
    if driver:
        return driver.get_screenshot_as_base64()


# 这个级别的装饰器前置步骤会被所有跨文件执行，先注销掉或者改下范围  scope='session'
# @pytest.fixture(scope='session', autouse=True)
# def browser(request):
#     global driver
#     if driver is None:
#         driver = webdriver.Chrome()
#
#     def end():
#         driver.quit()
#     request.addfinalizer(end)
#     return driver


def pytest_addoption(parser):
    parser.addoption(
        "--cmdopt", action="store", default="type1", help="my option: type1 or type2"
    )


@pytest.fixture
def cmdopt(request):
    return request.config.getoption("--cmdopt")


# 跳过装饰器
@pytest.mark.skip(reason="no way of currently testing this")
def test_the_unknown():
    ...


from selenium import webdriver
import time


@pytest.fixture(scope='session')
def driver(request):
    """open browser"""
    driver = webdriver.Chrome()
    driver.maximize_window()

    def end():
        print("全部用例执行完后  teardown quit driver")

_driver = None
@pytest.hookimpl(hookwrapper=True, tryfirst=True)
def pytest_runtest_makereport(item, call):
    print("------------------")

    # 获取钩子方法的调用结果
    outcome = yield
    print("用例执行结果", outcome)

    # 从钩子方法的调用结果种获取测试报告
    report = outcome.get_result()

    if report.when == "call" and report.failed:
        mode = "a" if os.path.exists("failuser") else "w"
        with open("failuser", mode) as f:
            if "tmpdir" in item.fixturenames:
                extra = "(%s)" % item.funcargs["tmpdir"]
            else:
                extra = ""
                f.write(report.nodeid + extra + "\n")
        if hasattr(_driver, "get_screenshot_as_png"):
            with allure.step("添加失败截图"):
                allure.attach(_driver.get_screenshot_as_png(), "失败截图", allure.attachment_type.PNG)
        print("测试报告： %s" % report)
        print('步骤：%s' % report.when)
        print('nodeid：%s' % report.nodeid)
        print('description:%s' % str(item.function.__doc__))
        print(('运行结果: %s' % report.outcome))

@pytest.fixture(scope='session')
def browser():
    global _driver
    if _driver is None:
        _driver =webdriver.Chrome()
    yield _driver
    print("1111111111")
    _driver.quit()


@pytest.fixture(scope="session", autouse="True")
def fix_a():
    print("setup 前置操作")
    yield
    print("teardown 后置操作")


def pytest_collection_modifyitems(session, items):
    """测试用例收集完成时，将收集到的item的name和nodeid的中文显示在控制台上"""
    print("收集到的测试用例:%s" % items)
    print("收集到的测试用例:%s" % items)
    # sort排序，根据用例名称item.name 排序
    # items.sort(key=lambda x: x.name)
    print("排序后的用例：%s" % items)
    for item in items:
        # unicode 转码前名称
        print("用例名:%s" % item.name)
        item.name = item.name.encode("utf-8").decode("unicode_escape")
        print("这个是什么1：", item.nodeid)
        # 这个是转码后的中文
        item._nodeid = item.nodeid.encode("utf-8").decode("unicode_escape")
        print("这个是什么2：", item._nodeid)
        # item.nodeid = item.nodeid.encode("utf-8").decode("unicode_escape")

def pytest_terminal_summary(terminalreporter, exitstatus, config):
    '''收集测试结果'''
    # print(terminalreporter.stats)
    total = terminalreporter._numcollected
    passed = len([i for i in terminalreporter.stats.get('passed', []) if i.when != 'teardown'])
    failed = len([i for i in terminalreporter.stats.get('failed', []) if i.when != 'teardown'])
    error = len([i for i in terminalreporter.stats.get('error', []) if i.when != 'teardown'])
    skipped = len([i for i in terminalreporter.stats.get('skipped', []) if i.when != 'teardown'])
    successful = len(terminalreporter.stats.get('passed', [])) / terminalreporter._numcollected * 100
    # terminalreporter._sessionstarttime 会话开始时间
    duration = time.time() - terminalreporter._sessionstarttime
    print('total times: %.2f' % duration, 'seconds')

    print("TOTAL=%s" % total + "\n")
    print("PASSED=%s" % passed + "\n")

    with open("result.txt", "w") as fp:
        fp.write("TOTAL=%s" % total + "\n")
        fp.write("PASSED=%s" % passed + "\n")
        fp.write("FAILED=%s" % failed + "\n")
        fp.write("ERROR=%s" % error + "\n")
        fp.write("SKIPPED=%s" % skipped + "\n")
        fp.write("SUCCESSFUL=%.2f%%" % successful + "\n")
        fp.write("TOTAL_TIMES=%.2fs" % duration)





# -----------------获取pytest.ini文件的配置信息
def pytest_addoption(parser):
    parser.addoption(
        "--cmdopt", action="store", default="type1", help="my option: type1 or type2"
    )
    # 添加参数到pytest.ini
    parser.addini('url', type=None, default="http://49.235.92.12:8200/", help='添加 url 访问地址参数')

# 获取 pytest.ini 配置参数
@pytest.fixture(scope="session")
def home_url(pytestconfig):
    # 下边的url就是pytest.ini 中的url，也可以取别的地址变量名称
    url = pytestconfig.getini('url')
    print("\n读取到配置文件的url地址：%s" % url)
    return url

# -----------------获取pytest.ini文件的配置信息


# 读取config下dbenv.yml 数据的方法
import yaml
@pytest.fixture(scope="session", autouse=True)
def dbinfo(request):
    dbfile = os.path.join(request.config.rootdir,
                        "config",
                        "dbenv.yml")
    print("dbinfo file path :%s" % dbfile)
    with open(dbfile, encoding="utf-8") as f:
        dbenv_config = yaml.load(f.read(), Loader=yaml.SafeLoader)
    print(dbenv_config)
    return dbenv_config